using System;
using System.Collections.Generic;

using Brilliance.utilities;

namespace Brilliance
{
    public abstract class Presenter : IPresenter
    {
        public abstract void Display();
        public event EventHandler<GenericEventArgs<INavigateAction>> Navigate;
        protected List<IView> viewsForAutomaticUnhook = new List<IView>();

        public IView View
        {
            set
            {
                viewsForAutomaticUnhook.Add(value);
                PostViewSet(value);
            }
        }

        protected virtual void PostViewSet(IView view)
        {
        }

        protected Presenter()
        {
            Navigate += delegate { };
        }

        private void OnViewDisposed(object sender, EventArgs e)
        {
            var view = sender as IView;
            if (view != null)
            {
                view.Disposed -= OnViewDisposed;
            }
            Dispose();
        }

        public void OnNavigate(GenericEventArgs<INavigateAction> e)
        {
            Navigate(this, e);
        }

        protected void OnNavigate(INavigateAction action)
        {
            OnNavigate(new GenericEventArgs<INavigateAction>(action));
        }

        protected void OnNavigate(string qualifier)
        {
            OnNavigate(new GenericEventArgs<INavigateAction>(qualifier));
        }

        public void Dispose()
        {
            ReflectUtil.RemoveEventHandlersFrom(IsAMethodOnThisInstance, viewsForAutomaticUnhook.ToArray());
            OnDispose();
        }

        private bool IsAMethodOnThisInstance(Delegate subscriber)
        {
            return ReferenceEquals(this, subscriber.Target);
        }

        protected virtual void OnDispose()
        {
        }
    }
}